package com.sky.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json，或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {//好像就是不要自己打,直接复制粘贴

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时，属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如，可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}
//专业答案：
//这是一个自定义的Jackson对象映射器，主要用于统一管理JSON与Java对象转换规则。核心作用如下：
//
//继承扩展：继承Jackson的ObjectMapper，重写默认的序列化/反序列化行为
//
//未知属性容错：
//
//FAIL_ON_UNKNOWN_PROPERTIES = false：前端传多余字段时不抛异常（避免因字段增减导致接口报错）
//
//时间格式化：
//
//统一处理Java8时间类型（LocalDateTime/LocalDate/LocalTime）
//
//定义标准格式：日期（yyyy-MM-dd），日期时间（yyyy-MM-dd HH:mm ），时间（HH:mm:ss ）
//
//模块注册：通过SimpleModule添加自定义序列化器/反序列化器，覆盖默认实现
//
//通俗答案：
//这个类相当于给系统配了一个"JSON翻译官"：
//
//翻译规则设定：
//
//遇到不认识的字段就当没看见（比如前端多传了"remark":"加急"不影响核心功能）
//
//统一所有时间的翻译格式（比如生日必须写成2000-01-01，时间写成14:30）
//
//专业词典扩展：
//
//给翻译官配了三本专用词典：
//
//如何把"2023-08-08 18:30"转成Java的LocalDateTime对象（反序列化）
//
//如何把Java的LocalDate对象转成"2023-08-08"（序列化）
//
//实际应用场景示例：
//
//订单提交接口接收JSON时，自动将createTime字符串转为LocalDateTime对象
//
//查询接口返回数据时，自动将LocalTime对象转为HH:mm:ss格式字符串
//
//代码关键点说明：
// 示例：前端传{"name":"奶茶", "expireTime":"2024-12-31 23:59"}时
//LocalDateTime expire = order.getExpireTime(); // 自动转为Java对象

// 后端返回对象包含LocalDate时：
// {"birthday":"2005-05-20"} 而不是默认的复杂格式
